package com.cy.java2;

/**
 * 线程通信的例子：使用两个线程打印1-100.线程1，线程2交替打印
 *
 * wait() 执行此方法，当前线程进入阻塞状态，并释放同步监视器
 * notify() 执行此方法，会唤醒被wait()的一个线程，如果有多个，就会唤醒优先级高的
 * notifyAll()执行此方法，会唤醒所有被wait()的线程
 *
 * 说明：
 * 1.wait(),notify() notifyAll() 都在同步
 *
 * 面试题：sleep()和wait()的异同
 * 1.相同点一旦执行方法都会执行是的当前线程进入阻塞状态
 * 2.不同点：a.两个方法声明的位置不同，Thread类中声明sleep()，Object类中声明wait()
 *          b.调用的要求不同，sleep()可以在任何需要的场景下调用，wait()必须使用在同步代码块中
 *          c.关于是否释放同步监视器的：如果两个方法都使用在同步代码块或同步方法中，sleep()不会释放锁
 *          wait()会释放锁
 *
 */

class Number implements Runnable{

    private int number = 1;

    @Override
    public void run(){
    while (true) {

        synchronized (this) {
            notify();
            if (number <=100) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":" + number);
                number++;

                try {
                    //使得调用如下wait()方法的线程进入阻塞状态
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                break;
            }
        }
    }
    }
}
public class CommunicationTest {
    public static void main(String[] args) {
        Number n1 = new Number();
        Thread t1 = new Thread(n1);
        Thread t2 = new Thread(n1);

        t1.setName("线程1");
        t2.setName("线程2");

        t1.start();
        t2.start();
    }

}
